import {DefaultConstructor, Second} from "utils"
import {Net, Send as fSend, WithJsonBody, WithHeader, Code, CodeError} from "foundation"
import {sleep} from "./sleep";
import {waitingRegistry} from "./ts";

export async function SendF<T extends object>(uri:string, requestF: ()=>Promise<object>
  , resType:DefaultConstructor<T>, net:Net, headers:Map<string, string> = new Map<string, string>()) {
  let [ret, err] = await fSend(uri, resType, net, WithJsonBody(await requestF()), WithHeader(headers));
  if (err == null) {
    return [ret, err]
  }

  if (err.code != Code.TokenExpire) {
    return [ret, err]
  }

  // 根据foundation的时序预定，出现此种情况，net已经恢复正常，则应该直接重试
  if (!net.is401()) {
    return await fSend(uri, resType, net, WithJsonBody(await requestF()), WithHeader(headers));
  }

  let registry = waitingRegistry.get(net.getPlugin().getName())
  if (registry === undefined) {
    return [ret, err]
  }

  return new Promise(resolve => {
    registry!.push(err1 =>{
      if (err1) {
        resolve([ret, err])
        return
      }

      let retry = async ():Promise<void> =>{
        resolve(await fSend(uri, resType, net, WithJsonBody(await requestF()), WithHeader(headers)))
      };
      retry().then()
    });


    sleep(60*Second).then(()=>{
      resolve([ret, new CodeError("time out")])
    })
  })
}
